import 'package:flutter/material.dart';
import 'package:x3_base_core/x3_base_core.dart';
import 'package:x3_component_core/utils/base_component_utils.dart';

///**
///* @fileName: base_select_query_date
///* @author: hrongyong
///* @date-time: 10/11/21 10:31 AM
///* @email: hrongyong@gmail.com
///* description: 选择查询日期
///* <fileName> <author> <date-time> <email> <description>
///* 文件名 作者姓名 创建时间 作者邮箱 文件描述
///*/
enum DateSortEnum { yyyy, mm, week, day, customize }

class BaseSelectQueryDate extends StatefulWidget {
  final DateTime startDateTime;
  final DateTime endDateTime;
  final Function(DateTime start, DateTime end) selectDate;

  const BaseSelectQueryDate({Key key, this.startDateTime, this.endDateTime, @required this.selectDate}) : super(key: key);

  @override
  _BaseSelectQueryDateState createState() => _BaseSelectQueryDateState();
}

class _BaseSelectQueryDateState extends State<BaseSelectQueryDate> {
  ///标题栏（appbar）
  static double _appbarHeight = 0.0;

  ///已经选择的时间类别
  DateSortEnum _sortEnum;

  ///已经选择类别里面的index
  int _selectIndex;

  ///已经选择的开始的时间
  DateTime _startDateTime;

  ///已经选择的结束的时间
  DateTime _endDateTime;

  ///按年列表
  List<String> _yyyyList = [];

  ///按月列表
  List<String> _mmList = [];

  ///按周列表
  List<String> _weekList = [];
  List<String> _dayList = ["今天", "昨天", "前天"];

  ///自定义模块
  String _customizeStart = "";
  String _customizeEnd = "";

  @override
  void initState() {
    super.initState();
    _appbarHeight = AppBar().preferredSize.height;
    _initData();
  }

  ///初始化数据
  void _initData() {
    _sortEnum = DateSortEnum.day;
    _selectIndex = -2;
    _startDateTime = widget.startDateTime == null ? DateTime.now() : widget.startDateTime;
    _endDateTime = widget.endDateTime == null ? DateTime.now() : widget.endDateTime;
    DateTime _dateTime = DateTime.now();
    //按年
    _yyyyList = List<String>.generate(5, (index) => "${_dateTime.year - index}");
    //按月
    _mmList = List<String>.generate(_dateTime.month, (index) => index == 0 ? "本月" : "${_dateTime.month - index} 月");
    //当前是当前年的第几周
    int weekOfYear = BaseDateUtil.weekOfYear(date: _dateTime);
    _weekList = List<String>.generate(weekOfYear, (index) => index == 0 ? "本周" : "${weekOfYear - index}");
    Map<String, dynamic> selectedMap = _filterNotSelected(currentTime: _dateTime, start: _startDateTime, end: _endDateTime);
    _sortEnum = selectedMap["key"];
    _selectIndex = selectedMap["index"];
    if (_sortEnum == DateSortEnum.customize) {
      _customizeStart = "${_startDateTime.year}-${BaseTransformUtil.format(_startDateTime.month)}-${BaseTransformUtil.format(_startDateTime.day)}";
      _customizeEnd = "${_endDateTime.year}-${BaseTransformUtil.format(_endDateTime.month)}-${BaseTransformUtil.format(_endDateTime.day)}";
    }
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      type: MaterialType.transparency,
      child: SafeArea(
        child: Center(
          child: Column(
            children: [
              SizedBox(height: _appbarHeight + 1),
              _title(),
              BaseComponentUtils.buildHorizontalDivider(),
              Container(
                width: double.infinity,
                constraints: BoxConstraints(minHeight: 200, maxHeight: MediaQuery.of(context).size.height * 0.7),
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                color: Colors.white,
                child: _buildSelectQueryDate(),
              ),
              Expanded(
                child: InkWell(
                  onTap: () {
                    BaseRouterUtil.getInstance().pop();
                  },
                  child: Container(color: Color(0XAA000000)),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _title() {
    return Container(
      height: 48,
      width: double.infinity,
      padding: EdgeInsets.symmetric(horizontal: 16.0),
      color: Colors.white,
      alignment: Alignment.centerLeft,
      child: Text("选择查询日期", style: TextStyle(fontSize: 14, color: Color(0xFF333333), fontWeight: FontWeight.bold)),
    );
  }

  Widget _buildSelectQueryDate() {
    return SingleChildScrollView(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          _selectSortDateItem(sortName: "按年", sortKey: DateSortEnum.yyyy, sortItemList: _yyyyList, isSelect: _sortEnum == DateSortEnum.yyyy, selectIndex: _selectIndex, selectEvent: (int index) => _byYearEvents(index, DateSortEnum.yyyy, currentIndex: _selectIndex)),
          _selectSortDateItem(sortName: "按月", sortKey: DateSortEnum.mm, sortItemList: _mmList, isSelect: _sortEnum == DateSortEnum.mm, selectIndex: _selectIndex, selectEvent: (int index) => _byMonthEvents(index, DateSortEnum.mm, currentIndex: _selectIndex)),
          _selectSortDateItem(sortName: "按周", sortKey: DateSortEnum.week, sortItemList: _weekList, isSelect: _sortEnum == DateSortEnum.week, selectIndex: _selectIndex, selectEvent: (int index) => _byWeekEvents(index, DateSortEnum.week, currentIndex: _selectIndex)),
          _selectSortDateItem(sortName: "按日", sortKey: DateSortEnum.day, sortItemList: _dayList, isSelect: _sortEnum == DateSortEnum.day, selectIndex: _selectIndex, selectEvent: (int index) => _byDayEvents(index, DateSortEnum.day, currentIndex: _selectIndex)),
          _buildCustomizeDate(start: _customizeStart, end: _customizeEnd, sortKey: DateSortEnum.customize, isSelect: _sortEnum == DateSortEnum.customize),
        ],
      ),
    );
  }

  ///自定义
  Widget _buildCustomizeDate({String start, String end, @required DateSortEnum sortKey, @required bool isSelect}) {
    return Container(
      height: 48,
      margin: EdgeInsets.symmetric(vertical: 8),
      padding: EdgeInsets.symmetric(vertical: 8),
      width: double.infinity,
      child: Row(
        children: [
          _buildSortName("自定义"),
          Expanded(child: _buildCustomizeDateItem(dateTime: start, onTap: _startTimeEvent, defaultName: "开始时间")),
          SizedBox(width: 12),
          Text("至"),
          SizedBox(width: 12),
          Expanded(child: _buildCustomizeDateItem(dateTime: end, onTap: _endTimeEvent, defaultName: "结束时间")),
        ],
      ),
    );
  }

  Widget _buildCustomizeDateItem({@required String defaultName, @required String dateTime, @required Function() onTap}) {
    return InkWell(
      onTap: onTap,
      child: Container(
        width: double.infinity,
        height: double.infinity,
        alignment: Alignment.centerLeft,
        padding: EdgeInsets.symmetric(horizontal: 4),
        decoration: BoxDecoration(
          color: Colors.white,
          border: Border.all(color: Color(dateTime.isEmpty ? 0xFFF3F3F3 : 0xFF333333), width: 1),
          borderRadius: BorderRadius.circular(4),
        ),
        child: Text(dateTime.isEmpty ? defaultName : dateTime, style: TextStyle(color: Color(0xFF333333))),
      ),
    );
  }

  /// sortName: 种类名称："按年"、"按月"、"按周"、"按天"、"自定义"
  /// sortItemList: 具体类别的
  Widget _selectSortDateItem({@required String sortName, @required List<String> sortItemList, @required DateSortEnum sortKey, @required bool isSelect, int selectIndex = -2, @required Function(int index) selectEvent}) {
    return Container(
      height: 48,
      margin: EdgeInsets.symmetric(vertical: 8),
      width: double.infinity,
      child: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
          double itemWidth = (constraints.maxWidth - 60 - 8 * 6) / 5;
          return Row(
            children: [
              _buildSortName(sortName),
              Expanded(child: _buildDateListView(sortKey: sortKey, itemWidth: itemWidth, sortItemList: sortItemList, selectIndex: isSelect ? selectIndex : -2, selectEvent: selectEvent)),
            ],
          );
        },
      ),
    );
  }

  ///各个类别的listview
  Widget _buildDateListView({@required List<String> sortItemList, @required DateSortEnum sortKey, @required double itemWidth, int selectIndex = -2, @required Function(int index) selectEvent}) {
    return Container(
      height: 48,
      decoration: BoxDecoration(
        color: Color.fromARGB(255, 248, 242, 251),
        borderRadius: BorderRadius.circular(24),
      ),
      padding: EdgeInsets.symmetric(horizontal: 4, vertical: 8),
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: sortItemList.length,
        itemBuilder: (BuildContext context, int index) {
          return InkWell(
            onTap: () => selectEvent(index),
            child: Container(
              height: double.infinity,
              width: itemWidth,
              margin: EdgeInsets.symmetric(horizontal: 4),
              alignment: Alignment.center,
              decoration: BoxDecoration(color: index == selectIndex ? Color(0xFFFF004F) : Colors.white, borderRadius: BorderRadius.circular(24)),
              child: Text(sortItemList[index], style: TextStyle(color: index == selectIndex ? Colors.white : Color(0xFF333333))),
            ),
          );
        },
      ),
    );
  }

  Widget _buildSortName(String sortName) {
    return Container(
      width: 60,
      alignment: Alignment.centerLeft,
      child: Text(
        sortName,
        style: TextStyle(fontSize: 14, color: Color(0xFF333333), fontWeight: FontWeight.bold),
      ),
    );
  }

  ///过滤未选择
  ///返回已选择的key和index
  Map<String, dynamic> _filterNotSelected({@required DateTime start, @required DateTime end, @required DateTime currentTime}) {
    ///如果有一个为空的则，说明
    if (start == null || end == null) return {"key": DateSortEnum.customize, "index": -2};

    if (start.year == end.year && start.month == end.month && start.day == end.day) {
      ///按日
      //昨天
      DateTime _yesterday = currentTime.subtract(Duration(days: 1));
      //前天
      DateTime beforeYesterday = _yesterday.subtract(Duration(days: 1));
      if (start.month == currentTime.month && start.day == currentTime.day) {
        //今天
        return {"key": DateSortEnum.day, "index": 0};
      }
      if (start.year == _yesterday.year && start.month == _yesterday.month && start.day == _yesterday.day) {
        //昨天
        return {"key": DateSortEnum.day, "index": 1};
      }
      if (start.year == beforeYesterday.year && start.month == beforeYesterday.month && start.day == beforeYesterday.day) {
        //前天
        return {"key": DateSortEnum.day, "index": 2};
      }
    }

    if (start.year == end.year && start.year == currentTime.year) {
      ///按周 1月的第一周或者12月的最后一周有可能跨年，其余的周都必须满7天
      ///当前是当前年的第几周
      int weekOfYear = BaseDateUtil.weekOfYear(date: currentTime);

      ///当前年的第一周
      List<DateTime> theFirstWeek = BaseDateUtil.weekToDayFormat(1, year: start.year);
      DateTime theFirstWeekStart = theFirstWeek[0];
      DateTime theFirstWeekEnd = theFirstWeek[1];
      bool isFirstWeek = (start.year == theFirstWeekStart.year && start.month == 1 && start.day == 31) && (end.year == theFirstWeekEnd.year && end.month == 1 && end.day == theFirstWeekEnd.day);
      if (isFirstWeek) return {"key": DateSortEnum.week, "index": weekOfYear - 1};

      ///当前周(也就是最新的一周、当前年已有的最后一周)
      List<DateTime> currentWeek = BaseDateUtil.weekToDayFormat(1, year: start.year);
      DateTime currentWeekStart = currentWeek[0];
      DateTime currentWeekEnd = currentWeek[1];
      bool isCurrentWeek = (start.year == currentWeekStart.year && start.month == currentWeekStart.month && start.day == currentWeekStart.day) && (end.year == currentWeekEnd.year && end.month == currentWeekEnd.month && end.day == currentWeekEnd.day);
      if (isCurrentWeek) return {"key": DateSortEnum.week, "index": weekOfYear - 1};

      ///剩余周都必须满七天
      if (start.month == end.month) {
        if (end.day - start.day + 1 == 7) {
          ///选择的周是当前年的第几周
          int _selectWeek = BaseDateUtil.weekOfYear(date: start);
          return {"key": DateSortEnum.week, "index": weekOfYear - _selectWeek};
        }
      }
      if (end.month - start.month == 1) {
        ///跨月了
        ///start的最后一天
        DateTime _startIsLastDay = DateTime(end.year, end.month, 1).subtract(Duration(days: 1));

        ///1 是因为_startIsLastDay没有加上本身
        if (_startIsLastDay.day - start.day + end.day + 1 == 7) {
          ///选择的周是当前年的第几周
          int _selectWeek = BaseDateUtil.weekOfYear(date: start.add(Duration(days: 1)));
          return {"key": DateSortEnum.week, "index": weekOfYear - _selectWeek};
        }
      }
    }

    if (start.year == end.year && start.year == currentTime.year && start.month == end.month) {
      ///按月 年月相同 比较是否是一个完整的月，逻辑：如果end加一天是下一个月的第一天，则end就是月的最后一天
      DateTime _nextMonth = end.add(Duration(days: 1));
      if (end.year == _nextMonth.year && end.month + 1 == _nextMonth.month) {
        ///如果同年 相差一个月 -> 成立
        int _index = currentTime.month - start.month;
        DateSortEnum _key = DateSortEnum.mm;
        return {"key": _key, "index": _index};
      }

      if (end.year + 1 == _nextMonth.year && _nextMonth.month == 1 && end.month == 12) {
        ///如果跨年 相差一个月 -> 成立
        int _index = currentTime.month - start.month;
        DateSortEnum _key = DateSortEnum.mm;
        return {"key": _key, "index": _index};
      }
    }

    if (start.year == end.year && start.month == 1 && end.month == 12 && start.day == 1 && end.day == 31 && start.year >= (currentTime.year - 4) && start.year <= currentTime.year) {
      ///按年 同年的第一天(20xx.01.01) 到最后一天(20xx.12.31) 并且按年的时间跨度是当前时间往前推5年。如: [2021,2020,2019,2018,2017]
      int _index = currentTime.year - start.year;
      DateSortEnum _key = DateSortEnum.yyyy;
      return {"key": _key, "index": _index};
    }

    ///剩下的都是自定义的。。。应该
    return {"key": DateSortEnum.customize, "index": -2};
  }

  ///选择按日的事件
  void _byDayEvents(int index, DateSortEnum sortEnum, {int currentIndex = -2}) {
    if (index != currentIndex || sortEnum != _sortEnum) {
      if (_sortEnum != sortEnum) _sortEnum = sortEnum;
      if (_selectIndex != index) _selectIndex = index;
      DateTime _now = DateTime.now();
      switch (index) {
        case 0:
          _startDateTime = DateTime(_now.year, _now.month, _now.day);
          _endDateTime = DateTime(_now.year, _now.month, _now.day, 23, 59, 59, 999);

          ///由于选择后就关闭，所以不再需要刷新
          // _initCustomizeTime();
          // setState(() {});
          widget.selectDate(_startDateTime, _endDateTime);
          BaseRouterUtil.getInstance().pop();
          break;
        case 1:
          DateTime _yesterday = _now.subtract(Duration(days: 1));
          _startDateTime = DateTime(_yesterday.year, _yesterday.month, _yesterday.day);
          _endDateTime = DateTime(_yesterday.year, _yesterday.month, _yesterday.day, 23, 59, 59, 999);

          ///由于选择后就关闭，所以不再需要刷新
          // _initCustomizeTime();
          // setState(() {});
          widget.selectDate(_startDateTime, _endDateTime);
          BaseRouterUtil.getInstance().pop();
          break;
        case 2:
          DateTime _beforeYesterday = _now.subtract(Duration(days: 2));
          _startDateTime = DateTime(_beforeYesterday.year, _beforeYesterday.month, _beforeYesterday.day);
          _endDateTime = DateTime(_beforeYesterday.year, _beforeYesterday.month, _beforeYesterday.day, 23, 59, 59, 999);

          ///由于选择后就关闭，所以不再需要刷新
          // _initCustomizeTime();
          // setState(() {});
          widget.selectDate(_startDateTime, _endDateTime);
          BaseRouterUtil.getInstance().pop();
          break;
      }
    }
  }

  ///选择按周的事件
  void _byWeekEvents(int index, DateSortEnum sortEnum, {int currentIndex = -2}) {
    if (index != currentIndex || sortEnum != _sortEnum) {
      if (_sortEnum != sortEnum) _sortEnum = sortEnum;
      if (_selectIndex != index) _selectIndex = index;
      DateTime _now = DateTime.now();
      //当前是当前年的第几周
      int weekOfYear = BaseDateUtil.weekOfYear(date: _now);
      List<DateTime> selectWeek = BaseDateUtil.weekToDayFormat(weekOfYear - index, year: _now.year);
      DateTime selectWeekStart = selectWeek[0];
      DateTime selectWeekEnd = selectWeek[1];
      _startDateTime = DateTime(selectWeekStart.year, selectWeekStart.month, selectWeekStart.day);
      _endDateTime = DateTime(selectWeekEnd.year, selectWeekEnd.month, selectWeekEnd.day, 23, 59, 59, 999);

      ///由于选择后就关闭，所以不再需要刷新
      // _initCustomizeTime();
      // setState(() {});
      widget.selectDate(_startDateTime, _endDateTime);
      BaseRouterUtil.getInstance().pop();
    }
  }

  ///选择按月的事件
  void _byMonthEvents(int index, DateSortEnum sortEnum, {int currentIndex = -2}) {
    if (index != currentIndex || sortEnum != _sortEnum) {
      if (_sortEnum != sortEnum) _sortEnum = sortEnum;
      if (_selectIndex != index) _selectIndex = index;

      DateTime _now = DateTime.now();
      _startDateTime = DateTime(_now.year, _now.month - index, 1);
      if (_now.month - index == 12) {
        _endDateTime = DateTime(_now.year, 12, 31, 23, 59, 59, 999);
      } else {
        //选择的月
        DateTime _selectMonth = DateTime(_now.year, _now.month - index + 1, 1).subtract(Duration(days: 1));
        _endDateTime = DateTime(_now.year, _now.month - index, _selectMonth.day, 23, 59, 59, 999);
      }

      ///由于选择后就关闭，所以不再需要刷新
      // _initCustomizeTime();
      // setState(() {});
      widget.selectDate(_startDateTime, _endDateTime);
      BaseRouterUtil.getInstance().pop();
    }
  }

  ///选择按年的事件
  void _byYearEvents(int index, DateSortEnum sortEnum, {int currentIndex = -2}) {
    if (index != currentIndex || sortEnum != _sortEnum) {
      if (_sortEnum != sortEnum) _sortEnum = sortEnum;
      if (_selectIndex != index) _selectIndex = index;
      DateTime _now = DateTime.now();
      _startDateTime = DateTime(_now.year - index, 1, 1);
      _endDateTime = DateTime(_now.year - index, 12, 31, 23, 59, 59, 999);

      ///由于选择后就关闭，所以不再需要刷新
      // _initCustomizeTime();
      // setState(() {});
      widget.selectDate(_startDateTime, _endDateTime);
      BaseRouterUtil.getInstance().pop();
    }
  }

  ///初始化自定义事件
  void _initCustomizeTime() {
    _customizeStart = "";
    _customizeEnd = "";
  }

  ///开始时间事件
  void _startTimeEvent() {
    BaseComponentUtils.openDatePicker(context, currentDate: _customizeStart.isNotEmpty ? _startDateTime : null, onDateChanged: (DateTime changed) {
      _customizeStart = "${changed.year}-${BaseTransformUtil.format(changed.month)}-${BaseTransformUtil.format(changed.day)}";
      _startDateTime = changed;
      _sortEnum = DateSortEnum.customize;
      _selectIndex = -2;

      ///当设置开始日期大于结束日期时，自动将结束日期等于开始日期
      if (_customizeEnd.isNotEmpty && _startDateTime.isAfter(_endDateTime)) {
        _endDateTime = DateTime(_startDateTime.year, _startDateTime.month, _startDateTime.day, 23, 59, 59, 999);
        _customizeEnd = _customizeStart;
      }
      if (_customizeStart.isNotEmpty && _customizeEnd.isNotEmpty) {
        ///由于选择后就关闭，所以不再需要刷新
        widget.selectDate(_startDateTime, _endDateTime);
        BaseRouterUtil.getInstance().pop();
      } else {
        setState(() {});
      }
    });
  }

  ///结束时间事件
  void _endTimeEvent() {
    BaseComponentUtils.openDatePicker(context, currentDate: _customizeEnd.isNotEmpty ? _endDateTime : null, onDateChanged: (DateTime changed) {
      _customizeEnd = "${changed.year}-${BaseTransformUtil.format(changed.month)}-${BaseTransformUtil.format(changed.day)}";
      _sortEnum = DateSortEnum.customize;
      _selectIndex = -2;
      _endDateTime = DateTime(changed.year, changed.month, changed.day, 23, 59, 59, 999);

      ///当设置结束日期小于开始日期时，自动将结束日期等于开始日期
      if (_customizeStart.isNotEmpty && _endDateTime.isBefore(_startDateTime)) {
        _endDateTime = DateTime(_startDateTime.year, _startDateTime.month, _startDateTime.day, 23, 59, 59, 999);
        _customizeEnd = _customizeStart;
      }
      if (_customizeStart.isNotEmpty && _customizeEnd.isNotEmpty) {
        ///由于选择后就关闭，所以不再需要刷新
        widget.selectDate(_startDateTime, _endDateTime);
        BaseRouterUtil.getInstance().pop();
      } else {
        setState(() {});
      }
    });
  }
}
